package com.zf.openfeign.caller.controller;

import io.github.resilience4j.timelimiter.annotation.TimeLimiter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * TimeLimiter 测试类
 */
@Slf4j
@RestController
@RequestMapping("/test/timelimiter")
public class TestTimeLimiterController {

    /**
     * TimeLimiter 注解的方法，必须返回一个异步结果（CompletionStage 子类）。
     * 指定“TimeLimiter实例、回调方法”，如果不配置回调方法，那么超时后直接抛出异常
     */
    @GetMapping("/myTmi")
    @TimeLimiter(name = "mytmi", fallbackMethod = "myTmiFallback")
    CompletableFuture<String> myTmi(@RequestParam(name = "name") String name) {
        // 将操作封装到异步中
        return CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(8);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return "你好, " + Optional.ofNullable(name).orElse("");
        });
    }

    /**
     * 超时回调方法：TimeLimiter抛出超时异常后，进入配置的回调方法：
     * 要求：和原始方法有一样的"返回类型、参数、最后一个参数是Throwable的子类"
     */
    CompletableFuture<String> myTmiFallback(String name, Throwable throwable) {
        log.error("错误回调：", throwable);
        return CompletableFuture.completedFuture("回调, 参数: " + Optional.ofNullable(name).orElse(""));
    }
}
